#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h> 
#include <stdlib.h>       
#include <string.h>
#include <pthread.h>
//#include <sys/sem.h>
#include <errno.h>
#include <sys/ipc.h>
//#include <sys/msg.h>
#include <sys/timeb.h>
#include <sys/socket.h>
//#include <sys/socketvar.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <semaphore.h>
#include <string.h>
#include <termios.h>
#include <linux/input.h>
#include <semaphore.h>
#include <linux/shm.h>
#include <asm/unistd.h>
#include <sys/poll.h>

#include "../common.h"

typedef enum _readOrWrite
{
		_read = 0,
		_write = 1,
		
		_maxReadOrWrite,
}ReadOrWrite;

typedef enum _codeIndex
{
		_openCode = 0,
		_closeCode,
		_vgaCode,
		_hdmiCode,
		
		_maxCodeIndex,	
}CodeIndex;
#define CODE_TYPE_NUM 4

typedef struct projectorTransitInfo
{
		CtrlCodeType code[CODE_TYPE_NUM];
		unsigned char codeLen[CODE_TYPE_NUM];
		unsigned int baud;
		unsigned char delayCloseTime;
		unsigned char delayOpenTime;
		unsigned char parityCheck;
		unsigned char manufactoryLen;
		unsigned char modelLen;
		TypeC256 manufactory;
		TypeC256 model;
}ProjectorTransitInfo;

typedef struct projectorCodeInfo
{
		RealCtrlCodeType realCode[CODE_TYPE_NUM];
		unsigned char realCodeLen[CODE_TYPE_NUM];
}ProjectorCodeInfo;

//protoSlaveType
enum _protoSlaveType
{
		_setAppOnlineWatchHtml					= 0x00,
		_getAppOnlineWatchHtml					= 0x01,
		_setAppCloudEduHtml							= 0x02,
		_getAppCloudEduHtml							= 0x03,
		_setAppUpdateServerDomainName		= 0x04,
		_getAppUpdateServerDomainName		= 0x05,
		
		_setProjectorCtrlCode						= 0x06,
		_getProjectorCtrlCode						= 0x07,
		_maxIndex,
};

static int setAppUpdateServerDomainName(struct recvData *recvData, struct packageFilter *pFilter);
static int getAppUpdateServerDomainName(struct recvData *recvData, struct packageFilter *pFilter);
static int setAppCloudEduHtml(struct recvData *recvData, struct packageFilter *pFilter);
static int getAppCloudEduHtml(struct recvData *recvData, struct packageFilter *pFilter);
static int setAppOnlineWatchHtml(struct recvData *recvData, struct packageFilter *pFilter);
static int getAppOnlineWatchHtml(struct recvData *recvData, struct packageFilter *pFilter);

static int setInfo(unsigned char index, struct recvData *recvData, struct packageFilter *pFilter);
static int getInfo(unsigned char index, struct recvData *recvData, struct packageFilter *pFilter);

static int writeInfo(unsigned char index, char *pValue);
static int readInfo(unsigned char index, char *pData);

static int preliminaryExplain(unsigned char index, char *pValue, char *key, ReadOrWrite readOrWrite);

static int writeCtrCode(ProjectorTransitInfo *t);
static int readCtrCode(ProjectorTransitInfo *t);

static int setProjectorCtrlCode(struct recvData *recvData, struct packageFilter *pFilter);
static int getProjectorCtrlCode(struct recvData *recvData, struct packageFilter *pFilter);
static void createConfigValue(char *code, unsigned char codeLen, char *asciiCode);
static void createMemoryData(char *code, unsigned char codeLen, unsigned char *realCode, unsigned char &realCodeLen);
static int createAsciiData(unsigned char *realCode, unsigned char realCodeLen, char *code, unsigned char &codeLen);

static int writeOneAppCloudEduHtml(unsigned char index, char *domainName);
static int readOneAppCloudEduHtml(unsigned char index, char *domainName);

extern SystemParam *pgSystemParam;

void deviceAppConfigServer(struct recvData *recvData)
{
		//static unsigned int inTimes = 0;
		//printf("into deviceAppConfigServer: inTimes=%u\n", inTimes);
		//inTimes ++;
		//printf("into deviceAppConfigServer\n");
		if(recvData == NULL)
		{
				printf("recvData == NULL ! {%s(%d)}\n",__FILE__,__LINE__);
				return;	
		}
	
		struct packageFilter filter;
		int ret = explainPackageHead(recvData, &filter);
		if(ret < 0)
		{
				printf("explainPackageHead fail ! {%s,%d}\n", __FILE__, __LINE__);
				return;	
		}
		
		switch(filter.protoSlaveType)
		{
				case _setAppUpdateServerDomainName:
				{
						setAppUpdateServerDomainName(recvData, &filter);
						break;	
				}
				case _getAppUpdateServerDomainName:
				{
						getAppUpdateServerDomainName(recvData, &filter);	
						break;
				}
				case _setAppCloudEduHtml:
				{
						setAppCloudEduHtml(recvData, &filter);	
						break;
				}
				case _getAppCloudEduHtml:
				{
						getAppCloudEduHtml(recvData, &filter);	
						break;
				}
				case _setAppOnlineWatchHtml:
				{
						setAppOnlineWatchHtml(recvData, &filter);	
						break;
				}
				case _getAppOnlineWatchHtml:
				{
						getAppOnlineWatchHtml(recvData, &filter);	
						break;
				}
				case _setProjectorCtrlCode:
				{
						setProjectorCtrlCode(recvData, &filter);	
						break;
				}
				case _getProjectorCtrlCode:
				{
						getProjectorCtrlCode(recvData, &filter);	
						break;
				}
				default:
				{
						printf("filter.protoSlaveType not right ! filter.protoSlaveType = %d {%s,%d}\n", filter.protoSlaveType, __FILE__,__LINE__);
						break;	
				}
		}		
}

static int setAppUpdateServerDomainName(struct recvData *recvData, struct packageFilter *pFilter)
{
		return setInfo(_setAppUpdateServerDomainName, recvData, pFilter);
}

static int getAppUpdateServerDomainName(struct recvData *recvData, struct packageFilter *pFilter)
{
		return getInfo(_getAppUpdateServerDomainName, recvData, pFilter);
}
static int setAppOnlineWatchHtml(struct recvData *recvData, struct packageFilter *pFilter)
{
		return setInfo(_setAppOnlineWatchHtml, recvData, pFilter);
}

static int getAppOnlineWatchHtml(struct recvData *recvData, struct packageFilter *pFilter)
{
		return getInfo(_getAppOnlineWatchHtml, recvData, pFilter);
}

static int setInfo(unsigned char index, struct recvData *recvData, struct packageFilter *pFilter)
{
		//printf("into setInfo\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen < 5)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		unsigned char len = pFilter->pData[4];
		char *pValue = (char *)(pFilter->pData + 5);
		pValue[len] = '\0'; //for safe
		printf("setInfo:index,pValue=%d,%s\n", index,pValue);
		
		int ret = writeInfo(index, pValue);
		unsigned char returnRet = (ret==0)?0:1;
		printf("returnRet = %d\n", returnRet);
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}

static int getInfo(unsigned char index, struct recvData *recvData, struct packageFilter *pFilter)
{
		//printf("into getInfo\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL !\n");
				return -3;	
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		//printf("into get 1\n");
		char pValue[80];
		int ret = readInfo(index, pValue);
		//printf("into get 2\n");
		unsigned char returnRet,len;
		if(ret == 0)
		{
				returnRet = 0;
				len = strlen(pValue);
		}
		else
		{
				returnRet = 1;
				len = 0;	
				pValue[0] = '\0';
		}
		printf("----getInfo:index,pValue=%d,%s\n", index,pValue);
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 6 + len;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		recvData->buf[headLen + 5] = len;
		if(len > 0)
		{
				memcpy(recvData->buf + headLen + 6, (unsigned char *)pValue, len);
		}
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		printf("packageSize,len = %d,%d\n", packageSize,len);
		return 0;
}
 
static int writeInfo(unsigned char index, char *pValue)
{
		char logBuf[80];
		char key[80];
		int ret;
		
		ret = preliminaryExplain(index, pValue, key, _write);
		if(ret < 0) return -1;
		
		ret = writeOneConfigValue(key, pValue);
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue fail ! ret = %d\n", ret);
				writeLog(logBuf, __FILE__, __LINE__);
				return -2;
		}
		
		return 0;
}

static int readInfo(unsigned char index, char *pValue)
{
		char logBuf[128];
		char key[80];
		int ret;
		//printf("1111\n");
		ret = preliminaryExplain(index, pValue, key, _read);
		//printf("index,key = %d,%s\n", index,key);
		//printf("2222\n");
		if(ret < 0) return -1;
		//printf("3333\n");
		ret = readOneConfigValue(key, pValue);
		//printf("4444\n");
		if(ret < 0)
		{
				sprintf(logBuf, "readOneConfigValue fail ! ret = %d\n", ret);
				writeLog(logBuf, __FILE__, __LINE__);
				return -2;
		}
		
		return 0;
}

static int preliminaryExplain(unsigned char index, char *pValue, char *key, ReadOrWrite readOrWrite)
{
		char logBuf[80];
		if(index > _maxIndex)
		{
				sprintf(logBuf, "index > _maxIndex ! index=%u, _maxIndex=%u\n", index,_maxIndex);
				writeLog(logBuf, __FILE__, __LINE__);
				return -1;
		}
		
		if(readOrWrite >= _maxReadOrWrite)
		{
				sprintf(logBuf, "readOrWrite > _maxReadOrWrite ! readOrWrite=%u, _maxReadORWrite=%u\n", readOrWrite,_maxReadOrWrite);
				writeLog(logBuf, __FILE__, __LINE__);
				return -2;
		}
		
		//simple judgement
		unsigned char sum = index + readOrWrite;
		if(sum % 2 != 1)
		{
				sprintf(logBuf, "sum % 2 != 1 index=%d,readOrWrite=%d\n", index,readOrWrite);
				writeLog(logBuf, __FILE__, __LINE__);
				return -3;
		}
		
		switch(index)
		{		
				case _setAppUpdateServerDomainName:
				case _getAppUpdateServerDomainName:
					strcpy(key, "app_update_server_ip_or_domain_name");
					break;
				case _setAppCloudEduHtml:
				case _getAppCloudEduHtml:
					strcpy(key, "app_cloud_edu_html");
					//sprintf(logBuf, "proto has been change ! it should not be deal here ! index = %u\n", index);
					//writeLog(logBuf, __FILE__, __LINE__);
					//return -5;
					break;
				case _setAppOnlineWatchHtml:
				case _getAppOnlineWatchHtml:
					strcpy(key, "app_online_watch_html");
					break;
				default:
					sprintf(logBuf, "unknow index for writeInfo ! index = %u\n", index);
					writeLog(logBuf, __FILE__, __LINE__);
					return -4;
					break;
		}

		return 0;
}


static int setProjectorCtrlCode(struct recvData *recvData, struct packageFilter *pFilter)
{
		printf("into setProjectorCtrlCode\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen < 6)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		int returnRet;
		ProjectorTransitInfo *t;
		t = (ProjectorTransitInfo *)malloc(sizeof(ProjectorTransitInfo));
		if(!t)
		{
				LOGD("malloc ProjectorTransitInfo fail !\n");	
				returnRet = 1;
		}
		else
		{
				memset(t, 0, sizeof(ProjectorTransitInfo));
				
				changeByteToUInt(t->baud, pFilter->pData + 4);
				t->delayCloseTime = pFilter->pData[8];
				t->delayOpenTime = pFilter->pData[9];
				t->parityCheck = pFilter->pData[10];
				
				unsigned char tmpLen;
				unsigned char *lenOffset = pFilter->pData + 11;
				unsigned char *codeOffest = pFilter->pData + 11 + CODE_TYPE_NUM + 2;
				for(unsigned char i=0; i<CODE_TYPE_NUM; i++)
				{
						tmpLen = *(lenOffset + i);
						t->codeLen[i] = tmpLen;
						memcpy(t->code[i], codeOffest, tmpLen);
						t->code[i][tmpLen] = '\0';
						codeOffest += tmpLen;
				}
				
				t->manufactoryLen = *(lenOffset + CODE_TYPE_NUM);
				t->modelLen = *(lenOffset + CODE_TYPE_NUM + 1);
				memcpy(t->manufactory, codeOffest, t->manufactoryLen);
				t->manufactory[t->manufactoryLen] = '\0';
				memcpy(t->model, codeOffest+t->manufactoryLen, t->modelLen);
				t->model[t->modelLen] = '\0';
				
				int ret = writeCtrCode(t);
				returnRet = (ret == 0) ? 0 : 1;
		}
	
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		printf("packageSize = %d\n", packageSize);
		
		if(t) free(t);
		return 0;
}

static int getProjectorCtrlCode(struct recvData *recvData, struct packageFilter *pFilter)
{
		printf("into getProjectorCtrlCode\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		int returnRet;
		ProjectorTransitInfo *t;
		t = (ProjectorTransitInfo *)malloc(sizeof(ProjectorTransitInfo));
		if(!t)
		{
				LOGD("malloc ProjectorTransitInfo fail !\n");
				returnRet = 1;
		}
		else
		{
				memset(t, 0, sizeof(ProjectorTransitInfo));
				
				int ret = readCtrCode(t);
				returnRet = (ret == 0) ? 0 : 1;
		}
		
		unsigned char dataDirection = 0x01;
		unsigned short dataLen = 4 + 1 +4+1+1+1 +1+1+1+1+1+1 +t->codeLen[0]+t->codeLen[1]+t->codeLen[2]+t->codeLen[3]+t->manufactoryLen+t->modelLen;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}

		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		printf("getProjectorCtrlCode:returnRet,dataLen = %d,%d\n", returnRet,dataLen);
		printf("codeLen = %u %u %u %u\n", t->codeLen[0],t->codeLen[1],t->codeLen[2],t->codeLen[3]);
		for (unsigned char i = 0; i < 4; i ++)
		{
			printf("code[%u] = ", i);
			for (unsigned char j = 0; j < t->codeLen[i]; j++)
			{
				printf("%c", t->code[i][j]);
			}
			printf("\n");
		}
		

		unsigned char *d = recvData->buf + headLen;
		*(d + 4) = returnRet;
		*(d + 5) = t->baud >> 24;*(d + 6) = t->baud >> 16;*(d + 7) = t->baud >> 8;*(d + 8) = t->baud;
		*(d + 9) = t->delayCloseTime;
		*(d + 10) = t->delayOpenTime;
		*(d + 11) = t->parityCheck;

		unsigned char tmpLen;
		unsigned char *lenOffset = d + 12;
		unsigned char *codeOffset = d + 12 + CODE_TYPE_NUM + 2;
		for(unsigned char i=0; i<CODE_TYPE_NUM; i++)
		{
				tmpLen = t->codeLen[i];
				*(lenOffset + i) = tmpLen;
				memcpy(codeOffset, t->code[i], tmpLen);
				codeOffset += tmpLen;
		}
		
		*(lenOffset + CODE_TYPE_NUM) = t->manufactoryLen;
		memcpy(codeOffset, t->manufactory, t->manufactoryLen);
		*(lenOffset + CODE_TYPE_NUM + 1) = t->modelLen;
		memcpy(codeOffset + t->manufactoryLen, t->model, t->modelLen);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		
		if(t) free(t);
		return 0;
}

static int writeOneCode(char *code, unsigned char codeLen, CodeIndex index, char *asciiCode, unsigned char *realCode, unsigned char &realCodeLen, char *logBuf)
{
		if(index > _maxCodeIndex)
		{
				sprintf(logBuf, "writeOneCode:index > _maxCodeIndex index=%d,_maxCodeIndex=%d\n", index,_maxCodeIndex);
				LOGD(logBuf);
				return -1;
		}
		
		char chBak = code[codeLen];
		code[codeLen] = '\0';
		sprintf(logBuf, "writeOneCode:index=%d,code=%s\n", index,code);
		LOGD(logBuf);
		code[codeLen] = chBak;
		
		asciiCode[0] = '\0';
		createConfigValue(code, codeLen, asciiCode);
		asciiCode[191] = '\0';
		
		char key[64];
		switch(index)
		{
				case _openCode:
					strcpy(key, "projector_open_code");	
					break;
				case _closeCode:
					strcpy(key, "projector_close_code");	
					break;
				case _vgaCode:
					strcpy(key, "projector_vga_code");	
					break;
				case _hdmiCode:
					strcpy(key, "projector_hdmi_code");	
					break;
				default:
					sprintf(logBuf, "writeOneCode:unknow index ! index=%d\n", index);
					LOGD(logBuf);
					return -2;
					break;
		}
		
		int ret = writeOneConfigValue(key, asciiCode);
		asciiCode[191] = '\0';
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue: write %s value fail ! value = %s", key, asciiCode);
				LOGD(logBuf);
				return -3;
		}
		
		//printf("before createMemoryData: codeLen,realCodeLen=%d,%d\n", codeLen,realCodeLen);
		createMemoryData(code, codeLen, realCode, realCodeLen);
		//printf("after createMemoryData: codeLen,realCodeLen=%d,%d\n", codeLen,realCodeLen);
		return 0;
}

static int writeCtrCode(ProjectorTransitInfo *t)
{
		char logBuf[256];
		char asciiCode[192];
		int ret;
		
		for(unsigned char i=0; i<CODE_TYPE_NUM; i++)
		{
				unsigned char cLen = t->codeLen[i];
				if((cLen>PROJECTOR_ASCII_CODE_MAX_LEN) || (cLen%2))	
				{
						sprintf(logBuf, "writeCtrCode param error ! openCodeLen=%d,closeCodeLen=%d,vgaCodeLen=%d,hdmiCodeLen=%d, PROJECTOR_ASCII_CODE_MAX_LEN=%d\n", 
							t->codeLen[0],t->codeLen[1],t->codeLen[2],t->codeLen[3], PROJECTOR_ASCII_CODE_MAX_LEN);
						LOGD(logBuf);
						return -21;
				}
				
				if(i==0 && cLen<2)
				{
						sprintf(logBuf, "writeCtrCode:open code len can not be 0 ! cLen=%d\n", cLen);
						LOGD(logBuf);
						return -22;
				}
				else if(i==1 && cLen<2)
				{
						sprintf(logBuf, "writeCtrCode:close code len can not be 0 ! cLen=%d\n", cLen);
						LOGD(logBuf);
						return -23;
				}
		}
		
		if(t->parityCheck > MAX_PARIRY) //0:'N' 1:'O' 2:'E'
		{
				sprintf(logBuf, "we do not support parityCheck value > %d ! parityCheck = %d\n", MAX_PARIRY, t->parityCheck);
				LOGD(logBuf);	
				return -24;
		}

		if(t->delayCloseTime < 10)
		{
				sprintf(logBuf, "we do not support delayCloseTime value < 10 ! delayCloseTime = %d\n", t->delayCloseTime);
				LOGD(logBuf);	
				return -25;
		}
		
		if(t->delayOpenTime < 2)
		{
				sprintf(logBuf, "we do not support delayOpenTime value < 2 ! delayOpenTime = %d\n", t->delayOpenTime);
				LOGD(logBuf);	
				return -26;
		}

		sprintf(logBuf, "into writeCtrCode:openCodeLen=%d,closeCodeLen=%d,vgaCodeLen=%d,hdmiCodeLen=%d, baud=%d,delayCloseTime=%d,delayOpenTime=%d,parityCheck=%d, manufactoryLen=%d,modelLen=%d\n",
		t->codeLen[0],t->codeLen[1],t->codeLen[2],t->codeLen[3],t->baud,t->delayCloseTime,t->delayOpenTime,t->parityCheck,t->manufactoryLen, t->modelLen);
		LOGD(logBuf);
		sprintf(logBuf, "manufactory, model=%s,%s\n", t->manufactory, t->model);
		LOGD(logBuf);
		
		ProjectorCodeInfo *c;
		c = (ProjectorCodeInfo*)malloc(sizeof(ProjectorCodeInfo));
		if(!c)
		{
				LOGD("malloc ProjectorCodeInfo fail !\n");	
				return -12;
		}
		memset(c, 0, sizeof(ProjectorCodeInfo));
		
		for(unsigned char i=0; i<(unsigned char)_maxCodeIndex; i++)
		{
				ret = writeOneCode((char *)(t->code[i]), t->codeLen[i], (CodeIndex)i, asciiCode, c->realCode[i], c->realCodeLen[i], logBuf);
				if(ret < 0) 
				{
						free(c);
						return -1-i;
				}
		}
		
		sprintf(asciiCode, "%u", t->baud);
		printf("baud ascii len is %d\n", strlen(asciiCode));
		ret = writeOneConfigValue("projector_baud", asciiCode);
		asciiCode[191] = '\0';
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue: write projector_baud fail ! value = %s", asciiCode);
				LOGD(logBuf);
				free(c);
				return -13;
		}
		
		sprintf(asciiCode, "%u", t->delayCloseTime);
		ret = writeOneConfigValue("projector_close_delay_time", asciiCode);
		asciiCode[191] = '\0';
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue: write projector_close_delay_time fail ! value = %s", asciiCode);
				LOGD(logBuf);
				free(c);
				return -14;
		}
		
		sprintf(asciiCode, "%u", t->delayOpenTime);
		ret = writeOneConfigValue("projector_open_delay_time", asciiCode);
		asciiCode[191] = '\0';
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue: write projector_open_delay_time fail ! value = %s", asciiCode);
				LOGD(logBuf);
				free(c);
				return -15;
		}
		
		sprintf(asciiCode, "%u", t->parityCheck);
		ret = writeOneConfigValue("projector_parity_check", asciiCode);
		asciiCode[191] = '\0';
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue: write projector_parity_check fail ! value = %s", asciiCode);
				LOGD(logBuf);
				free(c);
				return -16;
		}
		
		char bak;
		bak = t->manufactory[t->manufactoryLen];
		t->manufactory[t->manufactoryLen] = '\0';
		ret = writeOneConfigValue("projector_manufactory", t->manufactory);
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue: write projector_manufactory fail ! value = %s", asciiCode);
				LOGD(logBuf);
				free(c);
				return -17;
		}
		t->manufactory[t->manufactoryLen] = bak;
		
		bak = t->model[t->modelLen];
		t->model[t->modelLen] = '\0';
		 
		ret = writeOneConfigValue("projector_model", t->model);
		if(ret < 0)
		{
				sprintf(logBuf, "writeOneConfigValue: write projector_model fail ! value = %s", t->model);
				LOGD(logBuf);
				free(c);
				return -18;
		}
		t->model[t->modelLen] = bak;

		unsigned char *saveCode[] = {pgSystemParam->projectorOpenCode, pgSystemParam->projectorCloseCode, pgSystemParam->projectorVgaCode, pgSystemParam->projectorHdmiCode};
		unsigned char *saveCodeLen[] = {&(pgSystemParam->projectorOpenCodeNum), &(pgSystemParam->projectorCloseCodeNum),
			&(pgSystemParam->projectorVgaCodeNum), &(pgSystemParam->projectorHdmiCodeNum)};
			
		pthread_mutex_lock(&(pgSystemParam->projectorCodeLock));	
		for(unsigned char i=0; i<CODE_TYPE_NUM; i++)
		{
				memcpy(saveCode[i], c->realCode[i], PROJECTOR_CODE_MAX_LEN);
				*(saveCodeLen[i]) = c->realCodeLen[i];
		}
		pgSystemParam->projectorBaud = t->baud;
		pgSystemParam->projectorCutOffElectricityDelayTime = t->delayCloseTime;
		pgSystemParam->projectorSendOpenCodeDelayTime = t->delayOpenTime;
		pgSystemParam->projectorParitycheck = t->parityCheck;
		memcpy(pgSystemParam->projectorManufactory, t->manufactory, t->manufactoryLen);
		pgSystemParam->projectorManufactory[t->manufactoryLen] = '\0';
		memcpy(pgSystemParam->projectorModel, t->model, t->modelLen);
		pgSystemParam->projectorModel[t->modelLen] = '\0';
		pthread_mutex_unlock(&(pgSystemParam->projectorCodeLock));
		
		free(c);
		return 0;
}

static int readCtrCode(ProjectorTransitInfo *t)
{
		if(!pgSystemParam) return -1;
			
		char logBuf[256];
		projectorCodeInfo *c;
		c = (projectorCodeInfo *)malloc(sizeof(projectorCodeInfo));
		if(!c)
		{
				LOGD("malloc projectorCodeInfo fail !\n");
				return -2;
		}
		memset(c, 0, sizeof(projectorCodeInfo));
		
		unsigned char *saveCode[] = {pgSystemParam->projectorOpenCode, pgSystemParam->projectorCloseCode, pgSystemParam->projectorVgaCode, pgSystemParam->projectorHdmiCode};
		unsigned char *saveCodeLen[] = {&(pgSystemParam->projectorOpenCodeNum), &(pgSystemParam->projectorCloseCodeNum),
			&(pgSystemParam->projectorVgaCodeNum), &(pgSystemParam->projectorHdmiCodeNum)};
			
		pthread_mutex_lock(&(pgSystemParam->projectorCodeLock));	
		for(unsigned char i=0; i<CODE_TYPE_NUM; i++)
		{
				memcpy(c->realCode[i], saveCode[i], PROJECTOR_CODE_MAX_LEN);
				c->realCodeLen[i] = *(saveCodeLen[i]);
		}
		//printf("dddkalmfc 2\n");
		t->baud = pgSystemParam->projectorBaud;
		t->delayCloseTime = pgSystemParam->projectorCutOffElectricityDelayTime & 0x000000FF;
		t->delayOpenTime = pgSystemParam->projectorSendOpenCodeDelayTime & 0x000000FF;
		t->parityCheck = pgSystemParam->projectorParitycheck;
		strcpy(t->manufactory, pgSystemParam->projectorManufactory);
		t->manufactoryLen = strlen(pgSystemParam->projectorManufactory);
		t->manufactory[t->manufactoryLen] = '\0';
		strcpy(t->model, pgSystemParam->projectorModel);
		t->modelLen = strlen(pgSystemParam->projectorModel);
		t->model[t->modelLen] = '\0';
		pthread_mutex_unlock(&(pgSystemParam->projectorCodeLock));
		//printf("dddkalmfc 1\n");
		for(unsigned char i=0; i<CODE_TYPE_NUM; i++)
		{
				createAsciiData(c->realCode[i], c->realCodeLen[i], t->code[i], t->codeLen[i]);
		}
		free(c);
		
		/*printf("read:manufactory,len,model,len = %s,%d,%s,%d\n", t->manufactory,t->manufactoryLen,t->model,t->modelLen);
		printf("baud,close,open,parity = %d,%d,%d,%d\n", t->baud,t->delayCloseTime,t->delayOpenTime,t->parityCheck);
		printf("openCode = %s, openCodeLen = %d, closeCode = %s, closeCodeLen = %d\n", t->code[0], t->codeLen[0], t->code[1], t->codeLen[1]);
		printf("vgaCode = %s, VgaCodeLen = %d, hdmiCode = %s, hdmiCodeLen = %d\n", t->code[2], t->codeLen[2], t->code[3], t->codeLen[3]);*/
		return 0;
}

static void createConfigValue(char *code, unsigned char codeLen, char *asciiCode)
{
		unsigned char in = 0;
		unsigned char out = 0;
		
		while(in < codeLen)
		{
				asciiCode[out] = code[in];
				asciiCode[out + 1] = code[in + 1];
				asciiCode[out + 2] = ',';
				in += 2;
				out += 3;
		}
	
		asciiCode[out - 1] = '\0';
}

static void createMemoryData(char *code, unsigned char codeLen, unsigned char *realCode, unsigned char &realCodeLen)
{
		unsigned char codeIndex = 0;
		unsigned char realCodeIndex = 0;
		unsigned char tmpValue;
		while(codeIndex < codeLen)
		{
				tmpValue = code[codeIndex];
				if(tmpValue >= 'A' && tmpValue <= 'F')
				{
						realCode[realCodeIndex] = (tmpValue - 'A' + 10) << 4;
				}
				else if(tmpValue >= 'a' && tmpValue <= 'f')
				{
						realCode[realCodeIndex] = (tmpValue - 'a' + 10) << 4;
				}
				else if(tmpValue >= '0' && tmpValue <= '9')
				{
						realCode[realCodeIndex] = (tmpValue - '0') << 4;
				}
				else
				{
						realCode[realCodeIndex] = 0;
				}
			
				tmpValue = code[codeIndex + 1];
				if(tmpValue >= 'A' && tmpValue <= 'F')
				{
						realCode[realCodeIndex] += (tmpValue - 'A' + 10);
				}
				else if(tmpValue >= 'a' && tmpValue <= 'f')
				{
						realCode[realCodeIndex] += (tmpValue - 'a' + 10);
				}
				else if(tmpValue >= '0' && tmpValue <= '9')
				{
						realCode[realCodeIndex] += (tmpValue - '0');
				}
				else
				{
						realCode[realCodeIndex] += 0;
				}
				
				codeIndex += 2;
				realCodeIndex ++;
		}
		
		realCodeLen = realCodeIndex;
}

static int createAsciiData(unsigned char *realCode, unsigned char realCodeLen, char *code, unsigned char &codeLen)
{
		if(!realCode || !realCodeLen || !code) return -1;
		
		unsigned char index = 0;
		unsigned char tmpValue;
		for(unsigned char i = 0; i < realCodeLen; i ++)
		{
				tmpValue = realCode[i] / 16;
				if(tmpValue < 10)
				{
						code[index] = tmpValue + '0';
				}
				else
				{
						code[index] = tmpValue - 10 + 'A';
				}

				tmpValue = realCode[i] % 16;
				if(tmpValue < 10)
				{
						code[index + 1] = tmpValue + '0';
				}
				else
				{
						code[index + 1] = tmpValue - 10 + 'A';
				}

				if(i == realCodeLen - 1)
				{
						code[index + 2] = '\0';
				}
					
				index += 2;
		}
		
		codeLen = index;
		code[codeLen] = '\0';
		return 0;
}


static int setAppCloudEduHtml(struct recvData *recvData, struct packageFilter *pFilter)
{
		//return setInfo(_setAppCloudEduHtml, recvData, pFilter);

		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen < 6)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		unsigned char domainNameLen = pFilter->pData[4] - 1;
		unsigned char index = pFilter->pData[5];
		char *domainName = (char *)(pFilter->pData + 6);
		domainName[domainNameLen] = '\0';
		printf("setAppCloudEduHtml:domainNameLen = %d\n", domainNameLen);
		int ret = writeOneAppCloudEduHtml(index, domainName);
		if(ret < 0)
		{
				char logBuf[128];
				sprintf(logBuf, "writeOneAppCloudEduHtml fail ! index = %d\n", index);
				writeLog(logBuf, __FILE__, __LINE__);
		}
		
		int returnRet = (ret == 0) ? 0 : 1;
		
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}

static int getAppCloudEduHtml(struct recvData *recvData, struct packageFilter *pFilter)
{
		//return getInfo(_getAppCloudEduHtml, recvData, pFilter);
		
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 5)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}
		
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		unsigned char index = pFilter->pData[4];
		char domainName[256];
		domainName[0] = '\0';
		
		int ret = readOneAppCloudEduHtml(index, domainName);
		if(ret < 0)
		{
				char logBuf[128];
				sprintf(logBuf, "readOneAppCloudEduHtml fail ! index = %d, ret = %d\n", index, ret);
				writeLog(logBuf, __FILE__, __LINE__);
		}
		domainName[255] = '\0';
		unsigned char domainNameLen = strlen(domainName);
		//printf("getAppCloudEduHtml:domainNameLen = %d\n", domainNameLen);
		int returnRet = (ret == 0) ? 0 : 1;
		
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 6 + domainNameLen;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		recvData->buf[headLen + 5] = domainNameLen; 
		memcpy(recvData->buf + headLen + 6, domainName, domainNameLen);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}
	
int testWrite(unsigned char index, char *domainName)
{
		writeOneAppCloudEduHtml(index, domainName);
}

static int writeOneAppCloudEduHtml(unsigned char index, char *domainName)
{
		printf("into writeOneAppCloudEduHtml: index = %d, domainName = %s\n", index,domainName);
		FILE *fpRead = fopen(pgSystemParam->cloudEduIpConfigDir,"rb");
		if(!fpRead)
		{
				char logBuf[128];
				sprintf(logBuf, "Failed to open pgSystemParam->cloudEduIpConfigDir file: %s\n", pgSystemParam->cloudEduIpConfigDir);	
				writeLog(logBuf, __FILE__, __LINE__);
				return -1;		
		}
	
		char writeFileDir[256];
		sprintf(writeFileDir, "%s_tmp", pgSystemParam->cloudEduIpConfigDir);
		FILE *fpWrite = fopen(writeFileDir, "wb");
		if(!fpWrite)
		{
				char logBuf[128];
				sprintf(logBuf, "write:Failed to open writeFileDir file: %s\n", writeFileDir);	
				writeLog(logBuf, __FILE__, __LINE__);
				fclose(fpRead);
				return -2;		
		}
	
		char cmd[256];
		unsigned char domainNameLen = strlen(domainName);
	
		printf("prepare to deal !\n");
		char pLine[1025];
		for(unsigned char i = 0; i < index; i ++)
		{
				if(!fgets(pLine, 1024, fpRead))
				{
						if(domainNameLen == 0)
						{
								char logBuf[128];
								sprintf(logBuf, "client want to delete a domain name but index is too big ! i,index = %d,%d\n", i,index);	
								writeLog(logBuf,  __FILE__, __LINE__);
								fclose(fpRead);
								fclose(fpWrite);
								sprintf(cmd,"rm -rf %s", writeFileDir);
								system(cmd);
								return -3;
						}
						else //add new one
						{
								printf("prepare add new one ! i = %d\n", i);
								fwrite(domainName, 1, strlen(domainName), fpWrite);	
								fclose(fpRead);
								fclose(fpWrite);
								sprintf(cmd,"rm -rf %s", pgSystemParam->cloudEduIpConfigDir);
								system(cmd);
								sprintf(cmd, "mv %s %s", writeFileDir, pgSystemParam->cloudEduIpConfigDir);
								system(cmd);
								sprintf(cmd, "chmod 666 %s", pgSystemParam->cloudEduIpConfigDir);
								system(cmd);
								return 0;
						}
				}
				else //copy line data
				{
						printf("conpy data %d\n", i);
						fwrite(pLine, 1, strlen(pLine), fpWrite);	
				}
		}
	
		printf("prepare to deal index\n");
		if(!fgets(pLine, 1024, fpRead))
		{
				if(domainNameLen == 0)
				{
						char logBuf[128];
						sprintf(logBuf, "client want to delete a domain name but index is too big ! index = %d,%d\n", index);	
						writeLog(logBuf,  __FILE__, __LINE__);
						fclose(fpRead);
						fclose(fpWrite);
						sprintf(cmd,"rm -rf %s", writeFileDir);
						system(cmd);
						return -3;
				}
				else //add new one
				{
						printf("prepare add new one ! index = %d\n", index);
						fwrite(domainName, 1, strlen(domainName), fpWrite);	
						fwrite("\r\n", 1, 2, fpWrite);
						fclose(fpRead);
						fclose(fpWrite);
						sprintf(cmd,"rm -rf %s", pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
						sprintf(cmd, "mv %s %s", writeFileDir, pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
						sprintf(cmd, "chmod 666 %s", pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
						return 0;
				}
		}
		else
		{
				if(domainNameLen == 0)
				{
						char logBuf[128];
						sprintf(logBuf, "client want to delete a domain name ! index = %d, domainName = %s\n", index,domainName);	
						writeLog(logBuf,  __FILE__, __LINE__);
						
						//write the other data to new file
						while(fgets(pLine, 1024, fpRead))
						{
								fwrite(pLine, 1, strlen(pLine), fpWrite);	
						}
						
						fclose(fpRead);
						fclose(fpWrite);
						sprintf(cmd,"rm -rf %s", pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
						sprintf(cmd, "mv %s %s", writeFileDir, pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
						sprintf(cmd, "chmod 666 %s", pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
				}
				else //change one
				{
						printf("prepare to change one !\n");
						fwrite(domainName, 1, strlen(domainName), fpWrite);	
						fwrite("\r\n", 1, 2, fpWrite);
						
						//write the other data to new file
						while(fgets(pLine, 1024, fpRead))
						{
								fwrite(pLine, 1, strlen(pLine), fpWrite);	
						}
						
						fclose(fpRead);
						fclose(fpWrite);
						printf("prepare remove %s\n", pgSystemParam->cloudEduIpConfigDir);
						sprintf(cmd,"rm -rf %s", pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
						sprintf(cmd, "mv %s %s", writeFileDir, pgSystemParam->cloudEduIpConfigDir);
						//printf("prepare to rename: %s\n", cmd);
						system(cmd);
						sprintf(cmd, "chmod 666 %s", pgSystemParam->cloudEduIpConfigDir);
						system(cmd);
				}
			
		}
		
		return 0;
}

static int readOneAppCloudEduHtml(unsigned char index, char *domainName)
{
		printf("into readOneAppCloudEduHtml: index = %d\n", index);
		FILE *fp = fopen(pgSystemParam->cloudEduIpConfigDir,"rb");
		if(!fp)
		{
				char logBuf[128];
				sprintf(logBuf, "read:Failed to open pgSystemParam->cloudEduIpConfigDir file: %s\n", pgSystemParam->cloudEduIpConfigDir);	
				writeLog(logBuf, __FILE__, __LINE__);
				return -1;		
		}
		
		char pLine[1025];
		char *returnPointer = NULL;
		for(unsigned char i = 0; i < index; i ++)
		{
				returnPointer = fgets(pLine, 1024, fp);
				if(!returnPointer)
				{
						char logBuf[128];
						sprintf(logBuf, "into last line ! i = %d, index = %d\n", i,index);
						writeLog(logBuf, __FILE__, __LINE__);
						fclose(fp);
						return -2;
				}
		}
		
		returnPointer = fgets(pLine, 1024, fp);
		if(!returnPointer) 
		{
				fclose(fp);
				return -3;
		}

		strcpy(domainName, pLine);
		fclose(fp);
		printf("readOneAppCloudEduHtml:index,domainName = %d,%s\n", index,domainName);
		return 0;	
}
